/**
 * 
 */
package jmath.eval;

import org.apache.commons.logging.*;
import javax.script.*;
import java.util.*;
import jmath.eval.data.*;
import jmath.function.*;

public class ScriptEvaluator extends IOFunction {

	private Log log = LogFactory.getLog(ScriptEvaluator.class);

	private ScriptEngine engine;

	private Map<String, Object> javaToScriptSystemObjects;

	private JavaToScriptUserObjectsCollection javaToScriptUserObjectsCollection;

	private static final String JAVASCRIPT_LANGUAGE = "JavaScript";
	
	private String scriptLanguage="JavaScript";

	private ScriptEngineManager manager;

	// private Map<String,ScriptEngineFactory> scriptEngineFactoryMap;

	public ScriptEvaluator() {
		manager = new ScriptEngineManager();
	}

	public void eval(String script) {
		if (engine == null) {
			init();
		}
		jMathConsole.message(ioUtils.getMessage("START_SCRIPT"));
		try {
			engine.eval(script);
		} catch (Exception ex) {
			String exMessage = ex.getMessage();
			jMathConsole.error(exMessage);
			log.debug(exMessage);
			return;
		}
		jMathConsole.message(ioUtils.getMessage("END_SCRIPT"));
	}

	public void eval(String script, String scriptLanguage) {
		if (!this.scriptLanguage.equals(scriptLanguage)) {
			init(scriptLanguage);			
		}
		eval(script);
	}

	public void init() {
		init(JAVASCRIPT_LANGUAGE);
	}

	public void init(String scriptLanguage) {		
		engine = manager.getEngineByName(scriptLanguage);
		if (engine == null) {
			jMathConsole.error("Unsupported Language : " + scriptLanguage);
			return;
		}
		this.scriptLanguage=scriptLanguage;
		for (String key : javaToScriptSystemObjects.keySet()) {
			engine.put(key, javaToScriptSystemObjects.get(key));
		}
		for (String key : javaToScriptUserObjectsCollection.getJavaToScriptUserObjects().keySet()) {
			engine.put(key, javaToScriptUserObjectsCollection.getJavaToScriptUserObjects().get(key));
		}
	}

	public void eval() {
		String script = jMathScripter.readScript();
		String language = null;
		if (script.trim().startsWith("~~")) {
			script = script.trim().substring(2);
			language = script.substring(0, script.indexOf("~~"));
			script = script.substring(script.indexOf("~~") + 2);
		}
		if (language != null && language.length() > 0) {
			eval(script, language);
		} else {
			eval(script);
		}
	}

	public void setJavaToScriptSystemObjects(Map<String, Object> javaToScriptSystemObjects) {
		this.javaToScriptSystemObjects = javaToScriptSystemObjects;
	}

	public void setJavaToScriptUserObjectsCollection(JavaToScriptUserObjectsCollection javaToScriptUserObjectsCollection) {
		this.javaToScriptUserObjectsCollection = javaToScriptUserObjectsCollection;
	}

	public void setScriptEngineFactoryMap(Map<String, ScriptEngineFactory> scriptEngineFactoryMap) {
		if (scriptEngineFactoryMap != null) {
			for (String scriptName : scriptEngineFactoryMap.keySet()) {
				manager.registerEngineName(scriptName, scriptEngineFactoryMap.get(scriptName));
			}
		}
		// this.scriptEngineFactoryMap = scriptEngineFactoryMap;
	}

}
